﻿#pragma once

#include <opencv2/opencv.hpp>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/features/moment_of_inertia_estimation.h>
#include <pcl/console/parse.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/features/boundary.h>
#include <math.h>
#include <boost/make_shared.hpp>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/covariance_sampling.h>
#include <pcl/filters/normal_space.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/boundary.h>
#include <pcl/io/ply_io.h>
#include<pcl/visualization/pcl_visualizer.h>

//基础点云类型定义
typedef pcl::PointXYZ Point;
typedef pcl::PointCloud<Point> PointCloud;
typedef pcl::PointXYZRGBA PointShow;
typedef pcl::PointCloud<PointShow> PointCloudShow;

class PclFun
{
public:
	PclFun();
	~PclFun();
	// 点云显示
	static void ShowCloud(const PointCloud::Ptr& pcloud, const std::string& sViewerName = "Cloud");

	// 获取最大的点云
	static PointCloud::Ptr GetMaxCloud(std::vector<PointCloud::Ptr> vCloudPtr);

	/****************点云分析**************/
	static PointCloud::Ptr ExtractIndicesCloud(const PointCloud::Ptr& pCloud,
		const pcl::PointIndices::Ptr& inliers);
	// 平面分割
	static PointCloud::Ptr PlaneSegmentation(const PointCloud::Ptr& pCloud, float fMaxDist,
		pcl::ModelCoefficients::Ptr pcoefficients);

	// 平面系数转欧拉角 std::vector<float>值分别代表（YA, XA，ZA, distance[原点到平面距离]）
	static std::vector<float> PlaneCoefficients2Euler(const pcl::ModelCoefficients::Ptr& coefficients);

	//剪切特定方向点云 根据向量方向进行裁剪
	static PointCloud::Ptr CropCloudNormalRange(PointCloud::Ptr& pCloud, float fNormalAngleRange, char Axis);
	//PCL点云转Opencv点云
	static cv::Mat PCLCloud2cvCloudMask(PointCloud::Ptr& pCloud, const int& iImageRows, const int& iImageClos,
		const cv::Mat& matCameraMatrix, const cv::Mat& matDistCoeffs);

	/****************************************************************************
	 * 功能: 计算点云最小包围盒信息
	 * 传参: cloud: 输入点云；rotationalMatrix：输出旋转矩阵 size：包围盒尺寸，center: 包围盒重心点坐标
	 * 返回值: 包围盒位置信息
	 ****************************************************************************/
	static Point CloudOBB(const PointCloud::Ptr& cloud, Eigen::Matrix3f& rotationalMatrix,
		Eigen::Vector3f& size);

};
